home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / COMMON.ZIP / 13.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-22  |  13.2 KB  |  601 lines

  1. This is 3 files all glued together, mode13.h, blit13.c and pack.c
  2.  
  3. mode13.h has a simple sprite def in it,
  4. blit13 has some simple mode13 drawing routines,
  5. and pack.c is a mode13 packer for faster drawing of transparent shapes.
  6.  
  7. ---------------------------------------
  8. Transparent shapes.
  9.  
  10. 1] Check EACH pixel, and only draw non-zero ones, skipping zero pixels.
  11.    This is the easiest to program, and the slowest, as there is an extra
  12.    cmp per pixel, and you can't use rep movs
  13.  
  14. 2] Pre-pack your sprite so that it is in a form that can be quickly drawn
  15.    transparently. The method included in this file uses a sinple
  16.    Run Length Encoding (RLE) scheme where the the sprite is converted:
  17.    All zero pixels are replaced with code to skip x pixels, all non-zero
  18.    pixels are replaced with code to draw x pixels.
  19.    Code to do this is below. For certain shapes this packing can be up
  20.    to three times faster than method 1]
  21.  
  22. ---------------------------------------
  23. Drawing to off-screen buffer
  24.  
  25. Use the LEA (Load Effective address opp to load a far ptr)
  26. eg
  27.  
  28. les di, dest  ;load es:di with the address in the dword dest
  29.  
  30. ---------------------------------------
  31.  
  32. // 1st file ---------------------------------------------------------
  33. /*
  34.  
  35.    mode13.h
  36.  
  37.    copyright 1993, Alec Russell, ALL rights reserved
  38.  
  39.    320x200, 256 color mode routines, BIOS mode 0x13
  40.  
  41. */
  42.  
  43. #ifndef DEF_MODE13
  44. #define DEF_MODE13 1
  45.  
  46. #define USHORT unsigned short;
  47.  
  48. // dead simple sprite struct
  49. typedef struct
  50.    {
  51.    USHORT width, height;
  52.    BYTE far *bitmap;
  53.    }
  54. shape_t;
  55.  
  56. typedef unsigned char far * FARPTR;
  57.  
  58. #define INPUT_STATUS_1  03dah   //Input Status 1 register
  59. #define INPUT_STATUS_0  03dah   //Input status 0 register
  60.  
  61. #endif
  62.  
  63. /* ----------------------- end of file ------------------------------- */
  64.  
  65. // start of blit13.c---------------------------------------------------
  66.  
  67. /*
  68.    Copyright 1993, Alec Russell, ALL rights reserved
  69.    Permission granted to use this as you wish.
  70.  
  71.    FILE :13blit.c
  72.  
  73.          mode 13 blit stuff  --- MODE 13 !!! 320x200 x 256 colurs
  74.  
  75.  
  76.    HISTORY:
  77.       created :  may 19, 1993
  78.       updates :
  79.  
  80. */
  81.  
  82. #pragma inline
  83.  
  84.  
  85. /*
  86.    draws to the screen directly.
  87.  
  88.    damn fast, bitmap drawing routine
  89.  
  90.    x, y, width, height all in pixels, mode 0x13 ONLY
  91.  
  92.    MAX width and height is 255!!!!!
  93.  
  94.    buffer pointer to a width by height array of bytes that are a bitmap
  95.  
  96.    x, y is position to display at, NO checking done for valid
  97.    co-ords etc...
  98.  
  99.    WIDTH MUST BE EVEN!!!!
  100.  
  101.  
  102. */
  103. /* ---------------------- put_blit() --------------------- March 23,1993 */
  104. void put_blit(FARPTR buffer, short x, short y, short width, short height)
  105. {
  106.    asm   {
  107.          push  ds
  108.          push  di
  109.  
  110.          /* calc start address in vido mem */
  111.          mov   ax, y
  112.          mov   bx, x
  113.          xchg  ah, al
  114.          add   bx, ax
  115.          shr   ax, 1
  116.          shr   ax, 1
  117.          add   bx, ax
  118.  
  119.          /* set up address registers for movsw */
  120.          mov   ax, 0xa000
  121.          mov   es, ax
  122.          mov   di, bx
  123.          lds   si, buffer
  124.  
  125.          /* set up width and adjustment for fast blat */
  126.          mov   dx, width
  127.          shr   dx, 1
  128.          mov   bx, 320
  129.          sub   bx, width
  130.          mov   ax, height
  131.          }
  132.  
  133.          /* blast each line */
  134. l1:
  135.    asm   {
  136.          mov   cx, dx
  137.          rep   movsw
  138.          add   di, bx
  139.          dec   ax
  140.          jnz   l1
  141.  
  142.          /* all done */
  143.          pop   di
  144.          pop   ds
  145.          }   
  146. }
  147.  
  148.  
  149.  
  150. /*
  151.    draws to any buffer that is 320x200 in size
  152.  
  153.    damn fast, bitmap drawing routine
  154.  
  155.    x, y, width, height all in pixels, mode 0x13 ONLY
  156.  
  157.    MAX width and height is 255!!!!!
  158.  
  159.    buffer pointer to a width by height array of bytes that are a bitmap
  160.  
  161.    x, y is position to display at, NO checking done for valid
  162.    co-ords etc...
  163.  
  164.    WIDTH MUST BE EVEN!!!!
  165.  
  166. */
  167. /* ---------------------- put_blit2() --------------------- March 23,1993 */
  168. void put_blit2(FARPTR buffer, short x, short y,
  169.               short width, short height,
  170.               FARPTR dest)
  171. {
  172.    asm   {
  173.          push  ds
  174.          push  di
  175.  
  176.          /* calc start address in vido mem */
  177.          mov   ax, y
  178.          mov   bx, x
  179.          xchg  ah, al
  180.          add   bx, ax
  181.          shr   ax, 1
  182.          shr   ax, 1
  183.          add   bx, ax
  184.  
  185.          /* set up address registers for movsw */
  186.          les   di, dest  // es:di points to start dest
  187.          add   di, bx    // make es:di point to x,y in dest
  188.  
  189.          lds   si, buffer
  190.  
  191.          /* set up width and adjustment for fast blat */
  192.          mov   dx, width
  193.          shr   dx, 1
  194.          mov   bx, 320
  195.          sub   bx, width
  196.          mov   ax, height
  197.          }
  198.  
  199.          /* blast each line */
  200. l1:
  201.    asm   {
  202.          mov   cx, dx
  203.          rep   movsw
  204.          add   di, bx
  205.          dec   ax
  206.          jnz   l1
  207.  
  208.          /* all done */
  209.          pop   di
  210.          pop   ds
  211.          }   
  212. }
  213.  
  214.  
  215.  
  216. #if 0
  217. // C version works just fine but SLOW, kept it so you can tell
  218. //   what the asm version does
  219. /* ----------------- put_blit_packed() --------------------- March 23,1993 */
  220. void put_blit_packed(char far *buffer, short x, short y, short width, short height)
  221. {
  222.    unsigned char num;
  223.    char far *vid;
  224.    unsigned short i;
  225.  
  226.    i=y*320 + x;
  227.    vid=MK_FP(0xa000, i);
  228.    i=320 - width;
  229.  
  230.    for ( y=0; y < height; y++ )
  231.       {
  232.       x=0;
  233.       while ( x < width )
  234.          {
  235.          if ( *buffer )
  236.             {
  237.             buffer++;
  238.             num=*buffer++;
  239.             while ( num-- )
  240.                {
  241.                *vid++=*buffer++;
  242.                x++;
  243.                }
  244.             }
  245.          else
  246.             {
  247.             buffer++;
  248.             num=*buffer++;
  249.             vid+=num;
  250.             x+=num;
  251.             }
  252.          }
  253.  
  254.       vid+=i;
  255.       }
  256.  
  257.  
  258. }
  259. #endif
  260.  
  261. /*
  262.  
  263.    put a shape packed with pack shape
  264.    run length encoded
  265.    0 byte next byte is number of bytes to skip
  266.    1 byte next byte is number of bytes to draw
  267.  
  268.    only useful for TRANSPARENT SHAPES
  269.  
  270.    MAX width and height is 255!!!!!
  271.  
  272.    all color zero areas will be transparent see pack.c for more
  273.  
  274. */
  275. void put_blit_packed(FARPTR buffer, short x, short y, short width, short height)
  276. {
  277.  
  278.    asm   {
  279.          push  ds
  280.          push  di
  281.  
  282.          /* calc start address in video mem */
  283.          mov   ax, y
  284.          mov   bx, x
  285.          xchg  ah, al
  286.          add   bx, ax
  287.          shr   ax, 1
  288.          shr   ax, 1
  289.          add   bx, ax
  290.  
  291.          /* set up address registers for movsw */
  292.          mov   ax, 0xa000
  293.          mov   es, ax
  294.          mov   di, bx
  295.  
  296.          /* to make this draw to off-screen buffer add a dest parm
  297.          FARPTR dest, and replace the above 3 lines with
  298.  
  299.          les   di, dest
  300.          add,  di, bx
  301.  
  302.          see put_blit2() for an example
  303.  
  304.          */
  305.  
  306.          lds   si, buffer
  307.  
  308.          /* set up width and adjustment for fast blat */
  309.          mov   dx, width
  310.          mov   bx, 320
  311.          sub   bx, width
  312.          mov   ax, height
  313.          xor   ch, ch
  314.          }
  315.  
  316.          /* draw/skip each line */
  317. l1:
  318.    asm   {
  319.          xor   dh, dh
  320.          }
  321. lm0:
  322.    asm   {
  323.          cmp   byte ptr [si], 1
  324.          je    do_string
  325.  
  326. /*       skip black pixels */
  327.          inc   si
  328.          mov   cl, [si]
  329.          add   di, cx
  330.          add   dh, cl
  331.          inc   si
  332.  
  333.          /* check if done one line */
  334.          cmp   dh, dl
  335.          jne   lm0
  336.  
  337.          /* done one line, move to next */
  338.          add   di, bx
  339.          dec   ax
  340.          jnz   l1
  341.  
  342.          jmp   short the_end
  343.          }
  344.  
  345.          /*    draw a string of pixels */
  346. do_string:             
  347.    asm   {
  348.          inc   si
  349.  
  350.          mov   cl, [si]
  351.          add   dh, cl
  352.          inc   si
  353.  
  354.          rep   movsb
  355.  
  356.          /* check if done one line */
  357.          cmp   dh, dl
  358.          jne   lm0
  359.  
  360.  
  361.          /* done one line, move to next */
  362.          add   di, bx
  363.          dec   ax
  364.          jnz   l1
  365.          }
  366. the_end:
  367.          /* all done */
  368.    asm   {
  369.          pop   di
  370.          pop   ds
  371.          }   
  372. }
  373.  
  374.  
  375. /*
  376.  
  377.    FAST and easy mode 13 clipping
  378.  
  379.    buffer - pointer to shape
  380.    x, y   - where to put CLIPPED section of shape
  381.    full_width - full width of shape
  382.    dx, dy - where in shape to start blit
  383.    width, height - of clipped section we are drawing
  384.  
  385.  
  386.    shape
  387.  
  388.    |<-------- full_width----->|
  389.    ----------------------------
  390.    |   /\|                    |
  391.    |   dy|                    |
  392.    |   | |                    |
  393.    |<dx->|<--width------>|    |
  394.    |------------------------  |
  395.    |     |               | /\ |
  396.    |     |               | |  |
  397.    |     |               | |  |
  398.    |     |               | |  |
  399.    |     |  this rect is | height
  400.    |     |drawn at x, y  | |  |
  401.    |     | on the screen | |  |
  402.    |     |               | |  |
  403.    |     |               | \/ |
  404.    |     -------------------  |
  405.    |                          |
  406.    |                          |
  407.    ----------------------------
  408.  
  409.  
  410. */
  411. /* ---------------------- put_blit_clipped() ------------- April 24,1993 */
  412. void put_blit_clipped(FARPTR buffer, short x, short y, short full_width,
  413.                       short d_x, short d_y, short width, short height)
  414. {
  415.    unsigned short w;
  416.  
  417.    asm   {
  418.          push  ds
  419.          push  di
  420.  
  421.          /* calc w */
  422.          mov   ax, full_width
  423.          sub   ax, width
  424.          mov   w, ax
  425.  
  426.          /* calc start adrress in buffer */
  427.          lds   si, buffer
  428.          mov   ax, full_width
  429.          mul   word ptr d_y
  430.          add   ax, d_x
  431.          add   si, ax
  432.  
  433.          /* calc start address in vido mem */
  434.          mov   ax, y
  435.          mov   bx, x
  436.          xchg  ah, al
  437.          add   bx, ax
  438.          shr   ax, 1
  439.          shr   ax, 1
  440.          add   bx, ax
  441.  
  442.          /* set up address registers for movsb */
  443.          mov   ax, 0xa000
  444.          mov   es, ax
  445.          mov   di, bx
  446.  
  447.          /* set up width and adjustment for fast blat */
  448.          mov   dx, width
  449.          mov   bx, 320
  450.          sub   bx, width
  451.          mov   ax, height
  452.          }
  453.  
  454.          /* blast each line */
  455. l1:
  456.    asm   {
  457.          mov   cx, dx
  458.          rep   movsb
  459.          add   di, bx
  460.          add   si, w
  461.          dec   ax
  462.          jnz   l1
  463.  
  464.          /* all done */
  465.          pop   di
  466.          pop   ds
  467.          }   
  468. }
  469.  
  470.  
  471. /* wait for vertical sync */
  472. /* ---------------------- wait_vert() -------------------- March 27,1993 */
  473. void wait_vert(void)
  474. {
  475.    asm   {
  476.          mov     dx,INPUT_STATUS_1
  477.          }
  478. WaitVS:
  479.    asm   {
  480.          in      al,dx
  481.          test    al,08h
  482.          jz      WaitVS  /* vertical sync is active high (1 = active) */
  483.          }
  484. }
  485.  
  486. /* wait for vertical sync */
  487. /* ---------------------- wait_vert() -------------------- March 27,1993 */
  488. void wait_not_vert(void)
  489. {
  490.    asm   {
  491.          mov     dx,INPUT_STATUS_1
  492.          }
  493. WaitVS:
  494.    asm   {
  495.          in      al,dx
  496.          test    al,08h
  497.          jnz      WaitVS  /* vertical sync is active high (1 = active) */
  498.          }
  499. }
  500.  
  501.  
  502. /* ------------------------------ end of file ------------------------- */
  503.  
  504. ; start of pack.c
  505.  
  506. /*
  507.  
  508.    copyright 1993, Alec Russell, all rights reserved
  509.  
  510.    stuff to pack shapes - a utility
  511.  
  512. */
  513.  
  514.  
  515.  
  516. #include <mode13.h>
  517.  
  518.  
  519. /*
  520.  
  521.    pack a shape to speed up drawing TRANSPARENT shapes
  522.  
  523.    run length encoded
  524.    0 byte next byte is number of bytes to skip
  525.    1 byte next byte is number of bytes to draw
  526.  
  527.    only useful for TRANSPARENT SHAPES
  528.  
  529.    all color zero areas will be transparent
  530.  
  531.    MAX width and height is 255!!!!!
  532.  
  533.    packed line by line for speed
  534.  
  535.    this is NOT a good way to pack stuff if interested in saving space
  536.  
  537.    Once packed, use put_blit_packed() to draw.
  538.    Of course you will want to pack everthing in advance.
  539.    I usually put the function below into a stand-alone util and
  540.    pre-pack my sprites, saving them to disk packed.
  541.  
  542. */
  543. /* ---------------------- pack_shape() ------------------- April 15,1993 */
  544. void pack_shape(shape_t *shp1, shape_t *shp2)
  545. {
  546.    char far *s0, far *s1, far *t;
  547.    short num, x, y;
  548.  
  549.    s0=shp1->bitmap;
  550.    s1=shp2->bitmap;
  551.  
  552.    for ( y=0; y < shp1->height; y++ )
  553.       {
  554.       x=0;
  555.       while ( x < shp1->width )
  556.          {
  557.          if ( *s0 )
  558.             {
  559.             /* bytes isn't a zero so copy over until end of line or a zero */
  560.             num=0;
  561.             *s1++=1;
  562.             t=s1;    /* save where the count goes */
  563.             s1++;
  564.  
  565.             /* copy and count non-zero bytes */
  566.             while ( *s0 && x < shp1->width )
  567.                {
  568.                num++;
  569.                x++;
  570.                *s1++=*s0++;
  571.                }
  572.  
  573.             /* store count */
  574.             *t=num;
  575.             }
  576.          else
  577.             {
  578.             /* count number of zeros to skip and store count */
  579.             num=1;
  580.             *s1++=0;
  581.             s0++;
  582.             x++;
  583.  
  584.             while ( *s0 == 0 && x < shp1->width )
  585.                {
  586.                num++;
  587.                x++;
  588.                s0++;
  589.                }
  590.  
  591.             *s1++=num;
  592.             }
  593.          }
  594.       }
  595.  
  596.  
  597. }
  598.  
  599. /* -------------------------- end of file -------------------------- */
  600.  
  601.